home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue31 / delcom / Properties.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-02-06  |  21.7 KB  |  535 lines

  1. unit Properties;
  2. {********************************************************************}
  3. {**  Unit : Properties                                             **}
  4. {**                                                                **}
  5. {**  Description : This unit contains the main object for the shell**}
  6. {**  extension and the two interface objects needed to implement   **}
  7. {**  a shell extension. The user interface code for the property   **}
  8. {**  page is held in the BMPPageProc                               **}
  9. {**                                                                **}
  10. {**  Version History :                                             **}
  11. {**                                                                **}
  12. {**  A0.01     Initial version started                   27/10/96  **}
  13. {**                                                                **}
  14. {** Copyright ⌐1996 David J. Fiddes                                **}
  15. {********************************************************************}
  16. interface
  17. uses
  18.   Windows, OLE2, ShlObj, ShellAPI, CommCtrl, SysUtils,
  19.   Global, PageDefn, Resource;
  20.  
  21. type
  22.   TShellExtInit = class; { forward identifiers }
  23.   TPropSheetExt = class;
  24.  
  25. {********************************************************************}
  26. {**  Object : TPropertiesExt                                       **}
  27. {**                                                                **}
  28. {**  Description : This is the main object for the shell extension.**}
  29. {**  The object contains pointers to the IShellExtInit and         **}
  30. {**  IShellPropSheetExt interfaces and implements most of their    **}
  31. {**  methods.                                                      **}
  32. {**                                                                **}
  33. {**  Version History :                                             **}
  34. {**                                                                **}
  35. {**  A0.01     Initial version started                   27/10/96  **}
  36. {**                                                                **}
  37. {********************************************************************}
  38.   TPropertiesExt = class(IUnknown)
  39.  
  40.   private
  41.     FRefCount : longint; { reference count for the object }
  42.  
  43.     ShellExtInit : TShellExtInit; { forward ptr to IShellExtInit interface }
  44.     PropSheetExt : TPropSheetExt; { forward ptr to IShellPropSheetExt interface }
  45.  
  46.     TheFile      : array[0..MAX_PATH] of char;
  47.  
  48.   public
  49.     constructor Create;
  50.     destructor Destroy; override;
  51.  
  52.     {** IUnknown interface **}
  53.     function QueryInterface(const iid: TIID; var obj):HResult; override;
  54.     function AddRef:Longint; override;
  55.     function Release:Longint; override;
  56.  
  57.     {** IShellExtInit interface implementation **}
  58.     function Initialize( pidlFolder : PItemIDList; lpdobj : IDataObject;
  59.                          hKeyProgID : HKEY): HResult; stdcall;
  60.  
  61.     {** IShellPropSheetExt interface implementation **}
  62.     function AddPages( lpfnAddPage : TFNAddPropSheetPage; lParam : LPARAM): HResult; stdcall;
  63.     function ReplacePage( uPageID : UINT; lpfnReplaceWith : TFNAddPropSheetPage;
  64.                           lParam : LPARAM): HResult; stdcall;
  65.  
  66.   end;
  67.  
  68.  
  69. {********************************************************************}
  70. {**  Object : TShellExtInit                                        **}
  71. {**                                                                **}
  72. {**  Description : This is the IShellExtInit interface             **}
  73. {**  implementation. It passes most of it's methods back to the    **}
  74. {**  main class object : TPropertiesExt                            **}
  75. {**                                                                **}
  76. {**  Version History :                                             **}
  77. {**                                                                **}
  78. {**  A0.01     Initial version started                   27/10/96  **}
  79. {**                                                                **}
  80. {********************************************************************}
  81.   TShellExtInit = class(IShellExtInit)
  82.  
  83.   private
  84.     FRefCount : longint; { reference count for the object }
  85.     Parent    : TPropertiesExt; { backpointer to parent }
  86.  
  87.   public
  88.     constructor Create( AParent : TPropertiesExt );
  89.     destructor Destroy; override;
  90.  
  91.     {** IUnknown interface **}
  92.     function QueryInterface(const iid: TIID; var obj):HResult; override;
  93.     function AddRef:Longint; override;
  94.     function Release:Longint; override;
  95.  
  96.     {** IShellExtInit interface implementation **}
  97.     function Initialize( pidlFolder : PItemIDList; lpdobj : IDataObject;
  98.                          hKeyProgID : HKEY): HResult; override;
  99.   end;
  100.  
  101.  
  102. {********************************************************************}
  103. {**  Object : TPropSheetExt                                 **}
  104. {**                                                                **}
  105. {**  Description : This is the IShellPropSheetExt interface        **}
  106. {**  implementation. It passes most of it's methods back to the    **}
  107. {**  main class object : TPropertiesExt                            **}
  108. {**                                                                **}
  109. {**  Version History :                                             **}
  110. {**                                                                **}
  111. {**  A0.01     Initial version started                   27/10/96  **}
  112. {**                                                                **}
  113. {********************************************************************}
  114.   TPropSheetExt = class(IShellPropSheetExt)
  115.  
  116.   private
  117.     FRefCount : longint; { reference count for the object }
  118.     Parent    : TPropertiesExt; { backpointer to parent }
  119.  
  120.   public
  121.     constructor Create( AParent : TPropertiesExt );
  122.     destructor Destroy; override;
  123.  
  124.     {** IUnknown interface **}
  125.     function QueryInterface(const iid: TIID; var obj):HResult; override;
  126.     function AddRef:Longint; override;
  127.     function Release:Longint; override;
  128.  
  129.     {** IShellPropSheetExt interface implementation **}
  130.     function AddPages( lpfnAddPage : TFNAddPropSheetPage; lParam : LPARAM): HResult; override;
  131.     function ReplacePage( uPageID : UINT; lpfnReplaceWith : TFNAddPropSheetPage;
  132.                           lParam : LPARAM): HResult; override;
  133.   end;
  134.  
  135.  
  136. {********************************************************************}
  137. implementation
  138.  
  139. {********************************************************************}
  140. {**  TPropertiesExt implementation                                 **}
  141. {**                                                                **}
  142.  
  143. {********************************************************************}
  144. {**  Method : TPropertiesExt.Create                                **}
  145. {**                                                                **}
  146. {**  This is the constructor for the main object. It also creates  **}
  147. {**  the two interface classes for the extension in addition to    **}
  148. {**  carrying out the standard reference counting setup.           **}
  149. {********************************************************************}
  150. constructor TPropertiesExt.Create;
  151. begin
  152.   inc(RefThisDLL); { I exist .'. keep me alive! }
  153.   FRefCount:=0; {zero to start - incremented by QueryInterface}
  154.  
  155.   {** Create the interface classes for later **}
  156.   ShellExtInit:=TShellExtInit.Create(Self);
  157.   PropSheetExt:=TPropSheetExt.Create(Self);
  158.  
  159. end;
  160.  
  161.  
  162. {********************************************************************}
  163. {**  Method : TPropertiesExt.Destroy                               **}
  164. {**                                                                **}
  165. {**  This is the destructor for the main object. It also removes   **}
  166. {**  the two interface classes for the extension and carries out   **}
  167. {**  standard reference counting stripdown.                        **}
  168. {********************************************************************}
  169. destructor TPropertiesExt.Destroy;
  170. begin
  171.   {** zap the interface classes **}
  172.   ShellExtInit.Destroy;
  173.   PropSheetExt.Destroy;
  174.  
  175.   dec(RefThisDLL);
  176. end;
  177.  
  178.  
  179. {********************************************************************}
  180. {**  Method : TPropertiesExt.QueryInterface                        **}
  181. {**                                                                **}
  182. {**  This is method returns a pointer to the requested interface.  **}
  183. {**  IUnknown always returns a pointer to Self. For IShellExtInit  **}
  184. {**  and IShellPropSheetExt it returns the appropriate object ptr. **}
  185. {********************************************************************}
  186. function TPropertiesExt.QueryInterface(const iid: TIID; var obj):HResult;
  187. var
  188.   hr : hResult;
  189. begin
  190.   pointer(obj):=nil;
  191.   hr:=E_NOINTERFACE;
  192.  
  193.   {** This should only be for us(i.e. not the interface classes **}
  194.   if ISEqualIID(iid,IID_IUnknown) then
  195.   begin
  196.     pointer(obj):=Self;
  197.     hr:=NOERROR;
  198.     AddRef;
  199.   end;
  200.  
  201.   {** If IShellExtInit interface then chuck pointer!**}
  202.   if ISEqualIID(iid,IID_IShellExtInit) then
  203.   begin
  204.     pointer(obj):=ShellExtInit;
  205.     hr:=NOERROR;
  206.     ShellExtInit.AddRef; { this then calls Self.AddRef }
  207.   end;
  208.  
  209.   {** If IShellPropSheetExt interface then chuck pointer! **}
  210.   if ISEqualIID(iid,IID_IShellPropSheetExt) then
  211.   begin
  212.     pointer(obj):=PropSheetExt;
  213.     hr:=NOERROR;
  214.     PropSheetExt.AddRef;
  215.   end;
  216.  
  217.   {** trap nasties **}
  218.   if pointer(obj)=nil then
  219.     hr:=E_NOINTERFACE;
  220.  
  221.   QueryInterface:=hr;
  222. end;
  223.  
  224.  
  225. {********************************************************************}
  226. {**  Method : TPropertiesExt.AddRef                                **}
  227. {**                                                                **}
  228. {**  This is method increments the reference count for this object **}
  229. {********************************************************************}
  230. function TPropertiesExt.AddRef:longint;
  231. begin
  232.   inc(FRefCount);
  233.   Result:=FRefCount;
  234. end;
  235.  
  236.  
  237. {********************************************************************}
  238. {**  Method : TPropertiesExt.Release                               **}
  239. {**                                                                **}
  240. {**  This is method decrements the reference count for this object **}
  241. {**  if it is zero it unloads the object.                          **}
  242. {********************************************************************}
  243. function TPropertiesExt.Release:longint;
  244. begin
  245.   dec(FRefCount);
  246.   Result:=FRefCount;
  247.   if FRefCount=0 then Free;
  248. end;
  249.  
  250.  
  251. {********************************************************************}
  252. {**  Method : TPropertiesExt.Initialize                            **}
  253. {**                                                                **}
  254. {**  This is method is called to setup the shell extension, findout**}
  255. {**  the files involved,etc. At the moment it does nothing....     **}
  256. {**  Bounced IShellExtInit::Initialize implementation.             **}
  257. {********************************************************************}
  258. function TPropertiesExt.Initialize( pidlFolder : PItemIDList; lpdobj : IDataObject;
  259.                                        hKeyProgID : HKEY): HResult;
  260. var
  261.   medium : TStgMedium;
  262.   fe     : TFormatEtc;
  263.   hr     : HResult;
  264. begin
  265.   FillChar(TheFile,sizeof(TheFile),0);
  266.   { Fill in the fe structure }
  267.   with fe do
  268.   begin
  269.     cfFormat:=CF_HDROP;
  270.     ptd:=nil;
  271.     dwAspect:=DVASPECT_CONTENT;
  272.     lindex:=-1;
  273.     tymed:=TYMED_HGLOBAL;
  274.   end;
  275.  
  276.   if lpdobj=nil then
  277.   begin
  278.     Result:=E_FAIL;
  279.     exit;
  280.   end;
  281.  
  282.   {** Render the data referenced by the IDataObject pointer to an HGLOBAL **}
  283.   {** storage medium in CF_HDROP format.                                  **}
  284.  
  285.   hr:=lpdobj.GetData(fe,medium);
  286.   if FAILED(hr) then
  287.   begin
  288.     Result:=E_FAIL;
  289.     exit;
  290.   end;
  291.  
  292.   {** If only one file is selected, retrieve the file name and store it in **}
  293.   {** m_szFile. Otherwise fail the call.                                   **}
  294.  
  295.   hr:=E_FAIL;
  296.  
  297.   if DragQueryFile(medium.hGlobal,-1,nil,0)=1 then
  298.   begin
  299.     DragQueryFile(medium.hGlobal,0,TheFile,sizeof(TheFile));
  300.     hr:=NO_ERROR;
  301.   end;
  302.  
  303.   {** Release the storage medium and return. **}
  304.   ReleaseStgMedium(medium);
  305.  
  306.   Result:=hr;
  307. end;
  308.  
  309.  
  310. {********************************************************************}
  311. {**  Method : TPropertiesExt.AddPages                              **}
  312. {**                                                                **}
  313. {**  This is method is called to add pages to the PropertySheet.   **}
  314. {**  This sets up a simple page which is dealt with by the dialog/ **}
  315. {**  callback functions in BMPPageProc                             **}
  316. {**  Bounced IShellPropSheetExt::AddPages implementation.          **}
  317. {********************************************************************}
  318. function TPropertiesExt.AddPages( lpfnAddPage : TFNAddPropSheetPage; lParam : LPARAM): HResult;
  319. var
  320.   psp   : TPropSheetPage;
  321.   hPage : hPropSheetPage;
  322.   FileStr : PChar;
  323. begin
  324.   {allocate memory for the filename and copy}
  325.   GetMem(FileStr,MAX_PATH+1);
  326.   StrCopy(FileStr,TheFile);
  327.  
  328.   FillChar(psp,sizeof(psp),0); { make sure it's clean }
  329.   with psp do
  330.   begin
  331.     dwSize:=sizeof(TPropSheetPage);
  332.     dwFlags:=PSP_USEREFPARENT OR PSP_USECALLBACK;
  333.     psp.hInstance:=system.hInstance;
  334.     pszTemplate:=MakeIntResource(Dlg_Details);
  335.     pfnDlgProc:=@PropExtDlgProc; { for the user interface stuff }
  336.     pfnCallback:=@PropExtCallback; { for setup - shutdown functions }
  337.     pcRefParent:=@RefThisDLL;
  338.     lParam:=longint(FileStr);{pass in string pointer}
  339.   end;
  340.  
  341.   hPage:=CreatePropertySheetPage(psp);
  342.   if hPage<>nil then { valid PropertySheetPage }
  343.     if not lpfnAddPage(hPage,lParam) then {add the page and check for OK}
  344.       DestroyPropertySheetPage(hPage);
  345.  
  346.   Result:=NOERROR;
  347. end;
  348.  
  349.  
  350. {********************************************************************}
  351. {**  Method : TPropertiesExt.ReplacePage                           **}
  352. {**                                                                **}
  353. {**  This is method is called to replacepages to the PropertySheet.**}
  354. {**  This is not required for anything other than ControlPanel apps**}
  355. {**  Bounced IShellPropSheetExt::ReplacePages implementation.      **}
  356. {********************************************************************}
  357. function TPropertiesExt.ReplacePage( uPageID : UINT; lpfnReplaceWith : TFNAddPropSheetPage;
  358.                                         lParam : LPARAM): HResult;
  359. begin
  360.   Result:=E_NOTIMPL; {we don't do ReplacePages so be honest!}
  361. end;
  362.  
  363.  
  364. {********************************************************************}
  365. {**  TShellExtInit implementation                                  **}
  366. {**                                                                **}
  367.  
  368. {********************************************************************}
  369. {**  Method : TShellExtInit.Create                                 **}
  370. {**                                                                **}
  371. {**  This is the constructor for the IShellExtInit interface       **}
  372. {**  object. This object carries out it's own ref. counting        **}
  373. {********************************************************************}
  374. constructor TShellExtInit.Create( AParent : TPropertiesExt );
  375. begin
  376.   FRefCount:=0; {zero to start - incremented by QueryInterface}
  377.   Parent:=AParent; { store pointer }
  378. end;
  379.  
  380.  
  381. {********************************************************************}
  382. {**  Method : TShellExtInit.Destroy                                **}
  383. {**                                                                **}
  384. {**  This is the destructor for the IShellExtInit interface        **}
  385. {**  object.                                                       **}
  386. {********************************************************************}
  387. destructor TShellExtInit.Destroy;
  388. begin
  389. end;
  390.  
  391.  
  392. {********************************************************************}
  393. {**  Method : TShellExtInit.QueryInterface                         **}
  394. {**                                                                **}
  395. {**  This is method delegates to it's parent which returns the     **}
  396. {**  appropriate pointer.                                          **}
  397. {********************************************************************}
  398. function TShellExtInit.QueryInterface(const iid: TIID; var obj):HResult;
  399. begin
  400.   QueryInterface:=Parent.QueryInterface(iid,obj);
  401. end;
  402.  
  403.  
  404. {********************************************************************}
  405. {**  Method : TShellExtInit.AddRef                                 **}
  406. {**                                                                **}
  407. {**  This is method increments the reference count.                **}
  408. {********************************************************************}
  409. function TShellExtInit.AddRef:longint;
  410. begin
  411.   Parent.AddRef;
  412.   inc(FRefCount);
  413.   Result:=FRefCount;
  414. end;
  415.  
  416.  
  417. {********************************************************************}
  418. {**  Method : TShellExtInit.Release                                **}
  419. {**                                                                **}
  420. {**  This is method decrements the reference count and if zero     **}
  421. {**  unloads the object.                                           **}
  422. {********************************************************************}
  423. function TShellExtInit.Release:longint;
  424. begin
  425.   Parent.Release;
  426.   dec(FRefCount);
  427.   Result:=FRefCount;
  428. end;
  429.  
  430.  
  431. {********************************************************************}
  432. {**  Method : TShellExtInit.Initialize                             **}
  433. {**                                                                **}
  434. {**  This is method is passed onto TPropertiesExt.Initialize       **}
  435. {********************************************************************}
  436. function TShellExtInit.Initialize( pidlFolder : PItemIDList; lpdobj : IDataObject;
  437.                                        hKeyProgID : HKEY): HResult;
  438. begin
  439.   Result:=Parent.Initialize(pidlFolder,lpdobj,hKeyProgID);
  440. end;
  441.  
  442.  
  443. {********************************************************************}
  444. {**  TPropSheetExt implementation                           **}
  445. {**                                                                **}
  446.  
  447. {********************************************************************}
  448. {**  Method : TPropSheetExt.Create                          **}
  449. {**                                                                **}
  450. {**  This is the constructor for the IShellPropSheetExt interface  **}
  451. {**  object. This object carries out it's own ref. counting        **}
  452. {********************************************************************}
  453. constructor TPropSheetExt.Create( AParent : TPropertiesExt );
  454. begin
  455.   FRefCount:=0; {zero to start - incremented by QueryInterface}
  456.   Parent:=AParent; { store pointer }
  457. end;
  458.  
  459.  
  460. {********************************************************************}
  461. {**  Method : TPropSheetExt.Destroy                         **}
  462. {**                                                                **}
  463. {**  This is the destructor for the IShellPropSheetExt interface   **}
  464. {**  object.                                                       **}
  465. {********************************************************************}
  466. destructor TPropSheetExt.Destroy;
  467. begin
  468. end;
  469.  
  470.  
  471. {********************************************************************}
  472. {**  Method : TPropSheetExt.QueryInterface                  **}
  473. {**                                                                **}
  474. {**  This is method delegates to it's parent which returns the     **}
  475. {**  appropriate pointer.                                          **}
  476. {********************************************************************}
  477. function TPropSheetExt.QueryInterface(const iid: TIID; var obj):HResult;
  478. begin
  479.   QueryInterface:=Parent.QueryInterface(iid,obj);
  480. end;
  481.  
  482.  
  483. {********************************************************************}
  484. {**  Method : TPropSheetExt.AddRef                          **}
  485. {**                                                                **}
  486. {**  This is method increments the reference count.                **}
  487. {********************************************************************}
  488. function TPropSheetExt.AddRef:longint;
  489. begin
  490.   inc(FRefCount);
  491.   Result:=FRefCount;
  492.   Parent.AddRef;
  493. end;
  494.  
  495.  
  496. {********************************************************************}
  497. {**  Method : TPropSheetExt.Release                         **}
  498. {**                                                                **}
  499. {**  This is method decrements the reference count and if zero     **}
  500. {**  unloads the object.                                           **}
  501. {********************************************************************}
  502. function TPropSheetExt.Release:longint;
  503. begin
  504.   dec(FRefCount);
  505.   Result:=FRefCount;
  506.   Parent.Release;
  507. end;
  508.  
  509.  
  510. {********************************************************************}
  511. {**  Method : TPropSheetExt.AddPages                        **}
  512. {**                                                                **}
  513. {**  This is method is passed onto TPropertiesExt.AddPages         **}
  514. {********************************************************************}
  515. function TPropSheetExt.AddPages( lpfnAddPage : TFNAddPropSheetPage; lParam : LPARAM): HResult;
  516. begin
  517.   Result:=Parent.AddPages(lpfnAddPage,lParam);
  518. end;
  519.  
  520.  
  521. {********************************************************************}
  522. {**  Method : TPropSheetExt.ReplacePAge                     **}
  523. {**                                                                **}
  524. {**  This is method is passed onto TPropertiesExt.ReplacePage      **}
  525. {********************************************************************}
  526. function TPropSheetExt.ReplacePage( uPageID : UINT; lpfnReplaceWith : TFNAddPropSheetPage;
  527.                                         lParam : LPARAM): HResult;
  528. begin
  529.   Result:=Parent.ReplacePage(uPageID,lpfnReplaceWith,lParam);
  530. end;
  531.  
  532.  
  533. end.
  534. {********************************************************************}
  535.